/**
 * 		-	ad-creatif	-
 * 		-	20/07/2012	-
 *
 * The state loaded by flixel, it can be considered as the enterframe function, 
 * taking care of collisions, cameras,  and initial loading
 * 
 **/
package {
	
	import blocks.*;
	
	import entities.*;
	
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.BaseTypes.Bullet;
	import org.flixel.plugin.photonstorm.FlxBar;
	import org.flixel.plugin.photonstorm.FlxCollision;
	
	import screens.FlxPaused;
	import screens.HudScreen;
	
	import tools.MyBullet;
	
	public class PlayState extends FlxState {
		
		public function PlayState() {}
		 
		override public function create():void {
			super.create();
			
			Registry.init(function():void {
				
				Registry.friendlyPool.add(Registry.bulletPool);
				Registry.hostilePool.add(Registry.enemyPool)
				Registry.entityPool.add(Registry.hostilePool);
				Registry.entityPool.add(Registry.friendlyPool);
				
				add(Registry.level.backgrounds);
				add(Registry.dynamicPool);
				add(Registry.solidTilesPool); 
				
				add(Registry.entityPool);
				add(Registry.level.firstgrounds)
				add(Registry.fx);
				add(Registry.hud);
				
				//Camera
				FlxG.bgColor = (Registry.gameInfos.template.backgroundColor) ? Registry.gameInfos.template.backgroundColor : 0xffcccccc;
				FlxG.worldBounds = new FlxRect(0, 0, Registry.level.ground.width, Registry.level.ground.height); //level size usefull for collisions
				FlxG.camera.setBounds(0, 0, Registry.level.ground.width, Registry.level.ground.height); //camera limits 
				FlxG.camera.follow(Registry.player, FlxCamera.STYLE_PLATFORMER); //camera follows
				FlxG.camera.deadzone = new FlxRect(400-Registry.player.width, 450-Registry.player.height); // offset to place player
				
				if(Registry.gameInfos.world.music) FlxSound(Registry.gameInfos.world.music).play();
				
				if(Registry.gameInfos['debugMode']){
					FlxG.debug = true; 
					FlxG.visualDebug = true;
				}
				
				add(Registry.pauseScreen);
			});
			
			FlxG.mouse.show(Registry.cursorPNG);
			
		}
		
		
		override public function update():void {
			super.update();
			if (Registry.loaded) {
				if (!Registry.paused) {
					if (FlxG.keys.justPressed('P') || FlxG.keys.justPressed('ESCAPE'))
						Registry.pause(this);
					
					//collisions
					if (Registry.entityPool && Registry.solidTilesPool && Registry.dynamicPool) {
						FlxG.collide(Registry.entityPool, Registry.solidTilesPool, entityHitBlock);	// block
						FlxG.overlap(Registry.entityPool, Registry.dynamicPool, entityHitBlock);  	// dynamics
						FlxG.overlap(Registry.hostilePool,Registry.friendlyPool, hostileVsFriendly);
					}
						
					if(Registry.gameInfos && Registry.gameInfos.controls.switchPlayerKey && FlxG.keys.justPressed(Registry.gameInfos.controls.switchPlayerKey)){
						Registry.player.abilities.attack('switch');
					}
				}
			}
		}
	
		
		
		
		// HOSTILES vs FRIENDLY
		private function hostileVsFriendly(hostile:FlxSprite, friendly:FlxObject):void{
			
			if(hostile is Enemy && !Entity(hostile)._isDying){
				if(friendly is MeleeAttack){
					hostile.hurt(MeleeAttack(friendly).damages);
					return;
				}
				else if(friendly is Player || friendly is MyBullet) {
					entityPerfectCollision(friendly as FlxObject, hostile as Entity);
					return;
				}
			}
			if(hostile is Bullet && friendly is Player){
				entityPerfectCollision(hostile as Bullet, friendly as Entity);
			}
		} 
		
		
		
		// ENTITY perfect collision
		private function entityPerfectCollision(object:FlxObject, target:Entity):void{
			if(FlxCollision.pixelPerfectCheck(object as FlxSprite, target as FlxSprite )) {
				if(object is MyBullet){
					var bullet:MyBullet = object as MyBullet;
					target.hurt(bullet.power);
					bullet.kill();
					return;
					
				} else if(object is Player){
					//if player touch an enemy
					Registry.fx.kickHisAss(object,target.x);
					object.hurt(Entity(target).infos.attack.meleeDamage);
					Registry.fx.particles(object,0xFFDD0000,3); //blood
				}
			}
		}
		
		
		
		// BULLETS vs BLOCK
		private function bulletHitBlock(bullet:MyBullet, block:FlxObject):void {
			if(bullet.parent is Player && block is Destructible && Player(bullet.parent).abilities.can('destroyWall')){
				var destructible:Destructible = block as Destructible;
				destructible.explodeBlock();
			}
			
			Registry.fx.particles(bullet, 0xFF889977, 2, 1);
			bullet.kill();
		}
		
		
		
		
		// ENTITY vs BLOCK
		private function entityHitBlock(entity:FlxObject, block:FlxObject):void{
			if(block is FlxBar) return;
			
			// shoot wall or destructibles walls
			if((block is FlxTilemap || block is Destructible) && entity is MyBullet){
				bulletHitBlock(MyBullet(entity), block);
				return;
			}
			if(entity is MeleeAttack && block is Destructible && Registry.player.abilities.can('destroyWall')){
				var destructible:Destructible = block as Destructible ;
				destructible.explodeBlock();
				return;
			}
			
			if(entity is Player){
				if(block is Collapse && entity.isTouching(FlxObject.FLOOR) && block!=active){
					Collapse(block).activate();
					return;
				}
				if(block is Collect){
					Collect(block).collecting();
					return;
				}
				if(block is Checkpoint || block is Trigger){
					block.active=true;
					return;
				}
				
				//trigger a trap
				if(block is GhostZone){
					GhostZone(block)._parent.activate();
					block.kill();
					Registry.dynamicPool.remove(block);
					return;
				}
			}
			
			
			// traps damages for everyone
			if (entity is Entity && !Entity(entity)._invincible) {
				if(block is FallingTrap || block is Trap){
					//block.solid = false;
					if(FlxCollision.pixelPerfectCheck(block as FlxSprite, entity as FlxSprite)) {
						//block.solid = true;
						if (block is FallingTrap) FallingTrap(block).explodeBlock();
						Registry.fx.kickHisAss(entity, block.x);
						entity.hurt(Trap(block).damages);
						return;
					}
				}
			}
		}
	
	}
}
